﻿#include "ObjectTreeView.h"
#include "LumDebug.h"

#include <QHeaderView>

using BaseClass = QTreeView;

struct ObjectTreeView::ObjectTreeViewData {
    QPointer<QStandardItemModel> model;
    QPointer<QObject> rootObject;
};

ObjectTreeView::~ObjectTreeView() { }

ObjectTreeView::ObjectTreeView(QWidget *parent) : BaseClass{parent} {
    d.reset(new ObjectTreeViewData);
}

void ObjectTreeView::setRootObject(QPointer<QObject> object) {
    auto actualObject = object;
    if (object->isWidgetType() && !object->isWindowType()) {
        const auto widget = qobject_cast<QWidget*>(object);
        if (widget) {
            actualObject = widget->topLevelWidget();
        }
    }

    if(d->rootObject == actualObject) {
        return ;
    }

    d->rootObject = actualObject;

    const auto model = this->model().data();
    model->invisibleRootItem()->removeRows(0, model->rowCount());
    addItem(actualObject, model->invisibleRootItem(), true);
    expandAll();
}

QObject *ObjectTreeView::currentObject() const {
    const auto &index = currentIndex();
    if(!index.isValid()) {
        return nullptr;
    }

    return index.data(Qt::UserRole).value<QPointer<QObject>>();
}

QPointer<QWidget> objectToWidget(QPointer<QObject> object) {
    if(!object || !object->isWidgetType()) {
        return nullptr;
    }
    return qobject_cast<QWidget*>(object);
}

QPointer<QStandardItemModel> ObjectTreeView::model() {
    auto &moxing = d->model;
    if(!moxing) {
        moxing = new QStandardItemModel;
        setModel(moxing);
        moxing->setColumnCount(2);
        moxing->setHorizontalHeaderLabels({"对象", "类型"});

        //header()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
        //header()->setSectionResizeMode(1, QHeaderView::Stretch);
    }
    return moxing;
}

void ObjectTreeView::currentChanged(const QModelIndex &current, const QModelIndex &previous) {
    Q_UNUSED(previous);
    emit currentObjectChanged(current.data(Qt::UserRole).value<QPointer<QObject>>());
}

QStandardItem* ObjectTreeView::addItem(QPointer<QObject> object, QStandardItem* parent, bool isRoot) {
    if (const auto widget = objectToWidget(object)) {
        //const auto& objectName = object->objectName();
        if (!isRoot && widget->isTopLevel()) {
            return nullptr;
        }
    } else {
        return nullptr;
    }
    
    const auto name_item = new QStandardItem;
    name_item->setData(object->objectName(), Qt::DisplayRole);
    name_item->setData(QVariant::fromValue<QPointer<QObject>>(object), Qt::UserRole);

    const auto class_item = new QStandardItem;
    class_item->setData(object->metaObject()->className(), Qt::DisplayRole);
    class_item->setData(QVariant::fromValue<QPointer<QObject>>(object), Qt::UserRole);

    for(const auto child : object->children()) {
        addItem(child, name_item);
    }

    parent->appendRow({ name_item, class_item});
    return name_item;
}
